package com.woniu.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

@Configuration
public class RabbitMQConfig {

    // 创建注册手机号队列
    @Bean
    public Queue registerPhoneQueue() {
        return new Queue("register_phone_queue");
    }

    // 创建登录手机号队列
    @Bean
    public Queue loginPhoneQueue() {
        return new Queue("login_phone_queue");
    }

    // 定义一个队列，并且设置过期时间以及死信转发交换机
    @Bean
    public Queue deleteCacheDelayQueue() {
        HashMap<String, Object> map = new HashMap<>();
        // 定义该队列中消息的生存时间，单位为毫秒
        map.put("x-message-ttl", 5 * 1000);
        // x-dead-letter-exchange 属性用于声明死信转发到的交换机
        map.put("x-dead-letter-exchange", "del_cache_delay_exchange");
        // x-dead-letter-routing-key 声明了这些死信在转发时携带的路由键名称
        map.put("x-dead-letter-routing-key", "delay");
        return new Queue("del_cache_delay_queue", true, false, false, map);
    }

    // 创建一个交换机用于转发过期的延迟消息
    @Bean
    public DirectExchange deleteCacheDelayExchange() {
        return new DirectExchange("del_cache_delay_exchange");
    }

    // 创建一个队列，对死信数据进行存储和消费
    @Bean
    public Queue delCacheQueue() {
        return new Queue("del_cache_queue");
    }

    // 绑定队列与交换机
    @Bean
    public Binding bindDelCacheQueue() {
        return BindingBuilder.bind(delCacheQueue()).to(deleteCacheDelayExchange()).with("delay");
    }

    // 定义一个队列，并且设置过期时间以及死信转发交换机
    @Bean
    public Queue pointOrderNumDelayQueue() {
        HashMap<String, Object> map = new HashMap<>();
        // 定义该队列中消息的生存时间，单位为毫秒
        map.put("x-message-ttl", 60 * 1000);
        // x-dead-letter-exchange 属性用于声明死信转发到的交换机
        map.put("x-dead-letter-exchange", "points_ordernum_delay_exchange");
        // x-dead-letter-routing-key 声明了这些死信在转发时携带的路由键名称
        map.put("x-dead-letter-routing-key", "pay");
        return new Queue("points_order_num_delay_queue", true, false, false, map);
    }

    // 创建一个交换机用于转发过期的延迟消息
    @Bean
    public DirectExchange pointsOrderNumDelayExchange() {
        return new DirectExchange("points_ordernum_delay_exchange");
    }

    // 创建一个队列，对死信数据进行存储和消费
    @Bean
    public Queue pointsOrderNumQueue() {
        return new Queue("points_order_queue");
    }

    // 绑定队列与交换机
    @Bean
    public Binding bindPointsOrderNumQueue() {
        return BindingBuilder.bind(pointsOrderNumQueue()).to(pointsOrderNumDelayExchange()).with("pay");
    }

    // 创建一个用于错误处理的交换机
    @Bean
    public DirectExchange errorExchange() {
        return new DirectExchange("error-ex");
    }

    // 创建一个用于存储错误消息的队列
    @Bean
    public Queue errorMessageQueue() {
        return new Queue("errorMessageQueue", true);
    }

    // 绑定错误消息队列与交换机
    @Bean
    public Binding bindingErrorExchange() {
        return BindingBuilder.bind(errorMessageQueue()).to(errorExchange()).with("error");
    }

    // 配置消息恢复策略
    @Bean
    public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate) {
        // 配置交换机和绑定键
        return new RepublishMessageRecoverer(rabbitTemplate, "error-ex", "error");
    }
}
